<template>
  <doc-alert title="上传下载" url="https://doc.iocoder.cn/file/" />
  <!-- 搜索 -->
  <ContentWrap>
    <el-form
      class="-mb-15px"
      :model="queryParams"
      ref="queryFormRef"
      :inline="true"
      label-width="68px"
    >
      <el-form-item label="文件路径" prop="path">
        <el-input
          v-model="queryParams.path"
          placeholder="请输入文件路径"
          clearable
          @keyup.enter="handleQuery"
          class="!w-240px"
        />
      </el-form-item>
      <el-form-item label="文件类型" prop="type" width="80">
        <el-input
          v-model="queryParams.type"
          placeholder="请输入文件类型"
          clearable
          @keyup.enter="handleQuery"
          class="!w-240px"
        />
      </el-form-item>
      <el-form-item label="文件分组" prop="classifyId">
        <el-select
          v-model="queryParams.classifyId"
          placeholder="请选择文件分组"
          clearable
          class="!w-240px"
        >
          <el-option
            v-for="classify in classifyList"
            :key="classify.id"
            :label="classify.name"
            :value="classify.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="创建时间" prop="createTime">
        <el-date-picker
          v-model="queryParams.createTime"
          value-format="YYYY-MM-DD HH:mm:ss"
          type="daterange"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
          class="!w-240px"
        />
      </el-form-item>
      <el-form-item>
        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
        <el-button type="primary" plain @click="openForm">
          <Icon icon="ep:upload" class="mr-5px" /> 上传文件
        </el-button>
      </el-form-item>
    </el-form>
  </ContentWrap>

  <!-- 列表 -->
  <ContentWrap>
    <div v-loading="loading">
      <!-- 文件卡片网格 -->
      <div class="file-grid">
        <div
          v-for="file in list"
          :key="file.id"
          class="file-grid-item"
        >
          <el-card shadow="hover" class="file-card h-full">
            <!-- 文件预览区域 -->
            <div class="file-preview mb-3">
              <el-image
                v-if="file.type && file.type.includes('image')"
                class="w-full h-48 object-cover rounded"
                :src="file.url"
                :preview-src-list="[file.url]"
                preview-teleported
                fit="cover"
              />
              <div
                v-else
                class="w-full h-48 bg-gray-100 rounded flex items-center justify-center"
              >
                <Icon
                  :icon="getFileIcon(file.type)"
                  class="text-6xl text-gray-400"
                />
              </div>
            </div>

            <!-- 文件信息 -->
            <div class="file-info">
              <div class="file-name font-medium mb-2 truncate" :title="file.name">
                {{ file.name }}
              </div>
              <div class="file-details text-sm text-gray-500 space-y-1">
                <div class="text-blue-600">分组: {{ file.classifyName || '默认分组' }}</div>
                <div class="flex justify-between">
                  <span>{{ fileSizeFormatter('', '', file.size) }}</span>
                  <span>{{ file.type }}</span>
                </div>
                <div>时间: {{ dateFormatter('', '', file.createTime) }}</div>
              </div>
            </div>

            <!-- 操作按钮 -->
            <div class="file-actions mt-2 flex justify-between items-center">
              <div class="flex space-x-1">
                <el-button
                  v-if="file.type && file.type.includes('pdf')"
                  size="small"
                  type="primary"
                  link
                  @click="window.open(file.url, '_blank')"
                >
                  预览
                </el-button>
                <el-button
                  v-else
                  size="small"
                  type="primary"
                  link
                  @click="downloadFile(file.url, file.name)"
                >
                  下载
                </el-button>
                <el-button
                  size="small"
                  type="success"
                  link
                  @click="copyToClipboard(file.url)"
                >
                  复制链接
                </el-button>
              </div>
              <el-button
                size="small"
                type="danger"
                link
                @click="handleDelete(file.id)"
                v-hasPermi="['infra:file:delete']"
              >
                删除
              </el-button>
            </div>
          </el-card>
        </div>
      </div>

      <!-- 空状态 -->
      <el-empty v-if="!loading && list.length === 0" description="暂无文件" />
    </div>
    <!-- 分页 -->
    <Pagination
      :total="total"
      v-model:page="queryParams.pageNo"
      v-model:limit="queryParams.pageSize"
      @pagination="getList"
    />
  </ContentWrap>

  <!-- 表单弹窗：添加/修改 -->
  <FileForm ref="formRef" @success="getList" />
</template>
<script lang="ts" setup>
import { fileSizeFormatter } from '@/utils'
import { dateFormatter } from '@/utils/formatTime'
import * as FileApi from '@/api/infra/file'
import { FileClassifyApi } from '@/api/infra/fileClassify'
import FileForm from './FileForm.vue'

defineOptions({ name: 'InfraFile' })

const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化

const loading = ref(true) // 列表的加载中
const total = ref(0) // 列表的总页数
const list = ref([]) // 列表的数据
const classifyList = ref([]) // 分类列表
const queryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  name: undefined,
  type: undefined,
  path: undefined,
  classifyId: undefined,
  createTime: []
})
const queryFormRef = ref() // 搜索的表单

/** 获取分类列表 */
const getClassifyList = async () => {
  try {
    const data = await FileClassifyApi.getFileClassifySimpleList()
    classifyList.value = data || []
  } catch (error) {
    console.error('获取分类列表失败:', error)
  }
}

/** 查询列表 */
const getList = async () => {
  loading.value = true
  try {
    const data = await FileApi.getFilePage(queryParams)
    list.value = data.list
    total.value = data.total
  } finally {
    loading.value = false
  }
}

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.pageNo = 1
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value.resetFields()
  handleQuery()
}

/** 添加/修改操作 */
const formRef = ref()
const openForm = () => {
  formRef.value.open()
}

/** 获取文件图标 */
const getFileIcon = (fileType: string) => {
  if (!fileType) return 'ep:document'

  if (fileType.includes('pdf')) return 'ep:document'
  if (fileType.includes('word') || fileType.includes('doc')) return 'ep:document'
  if (fileType.includes('excel') || fileType.includes('sheet')) return 'ep:document'
  if (fileType.includes('powerpoint') || fileType.includes('presentation')) return 'ep:document'
  if (fileType.includes('text') || fileType.includes('txt')) return 'ep:document'
  if (fileType.includes('video')) return 'ep:video-play'
  if (fileType.includes('audio')) return 'ep:headphones'
  if (fileType.includes('zip') || fileType.includes('rar') || fileType.includes('7z')) return 'ep:folder-opened'

  return 'ep:document'
}

/** 下载文件 */
const downloadFile = (url: string, filename: string) => {
  const link = document.createElement('a')
  link.href = url
  link.download = filename
  link.target = '_blank'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

/** 复制到剪贴板方法 */
const copyToClipboard = (text: string) => {
  navigator.clipboard.writeText(text).then(() => {
    message.success('复制成功')
  })
}

/** 删除按钮操作 */
const handleDelete = async (id: number) => {
  try {
    // 删除的二次确认
    await message.delConfirm()
    // 发起删除
    await FileApi.deleteFile(id)
    message.success(t('common.delSuccess'))
    // 刷新列表
    await getList()
  } catch {}
}

/** 初始化 **/
onMounted(() => {
  getClassifyList() // 获取分类列表用于筛选
  getList()
})
</script>

<style scoped>
.file-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 16px;
  margin-bottom: 16px;
}

@media (max-width: 1200px) {
  .file-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

@media (max-width: 992px) {
  .file-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 768px) {
  .file-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 576px) {
  .file-grid {
    grid-template-columns: 1fr;
  }
}

.file-grid-item {
  margin-bottom: 16px;
}

.file-card {
  transition: all 0.3s ease;
  border: 1px solid #e4e7ed;
  height: 360px;
  display: flex;
  flex-direction: column;
}

.file-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.file-preview {
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
}

.file-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 0 4px;
}

.file-name {
  font-size: 14px;
  line-height: 1.4;
}

.file-details {
  font-size: 12px;
}

.file-actions {
  border-top: 1px solid #f0f0f0;
  padding: 6px 0 0 0;
  margin-top: auto;
  height: 28px;
  flex-shrink: 0;
}

.file-actions .el-button {
  padding: 2px 4px;
  font-size: 11px;
  height: 22px;
}
</style>
